package jfconfig;

/**
 * Created : Apr 3, 2012
 *
 * @author pquiring
 */

import java.io.*;
import java.util.*;
import javax.swing.*;

import javaforce.*;
import javaforce.linux.*;

public class InterfacePanel extends javax.swing.JPanel {

  /**
   * Creates new form InterfacePanel
   */
  public InterfacePanel() {
    initComponents();
    listIFs();
    loadConfig();
  }

  /**
   * This method is called from within the constructor to initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is always
   * regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    jLabel1 = new javax.swing.JLabel();
    jToolBar1 = new javax.swing.JToolBar();
    back = new javax.swing.JButton();
    edit = new javax.swing.JButton();
    enable = new javax.swing.JButton();
    jScrollPane1 = new javax.swing.JScrollPane();
    list = new javax.swing.JList();
    status = new javax.swing.JLabel();

    jLabel1.setText("jLabel1");

    jToolBar1.setFloatable(false);
    jToolBar1.setRollover(true);

    back.setText("< Back");
    back.setFocusable(false);
    back.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    back.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    back.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        backActionPerformed(evt);
      }
    });
    jToolBar1.add(back);

    edit.setText("Edit");
    edit.setEnabled(false);
    edit.setFocusable(false);
    edit.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    edit.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    edit.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        editActionPerformed(evt);
      }
    });
    jToolBar1.add(edit);

    enable.setText("Enable");
    enable.setEnabled(false);
    enable.setFocusable(false);
    enable.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    enable.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    enable.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        enableActionPerformed(evt);
      }
    });
    jToolBar1.add(enable);

    list.setModel(model);
    list.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
      public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
        listValueChanged(evt);
      }
    });
    jScrollPane1.setViewportView(list);

    status.setText("Status : n/a");

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
    this.setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 376, Short.MAX_VALUE)
          .addComponent(status, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        .addContainerGap())
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 196, Short.MAX_VALUE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(status)
        .addContainerGap())
    );
  }// </editor-fold>//GEN-END:initComponents

  private void backActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_backActionPerformed
    ConfigApp.setPanel(new NetworkPanel());
  }//GEN-LAST:event_backActionPerformed

  private void enableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_enableActionPerformed
    toggleIF();
  }//GEN-LAST:event_enableActionPerformed

  private void editActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editActionPerformed
    String eth = (String)list.getSelectedValue();
    if (eth == null) return;
    Interface iface = getInterface(eth);
    InterfaceEditDialog dialog = new InterfaceEditDialog(ConfigApp.This, true, iface);
    dialog.setVisible(true);
    if (dialog.accepted) saveConfig();
  }//GEN-LAST:event_editActionPerformed

  private void listValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_listValueChanged
    isInterfaceActive();
  }//GEN-LAST:event_listValueChanged

  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JButton back;
  private javax.swing.JButton edit;
  private javax.swing.JButton enable;
  private javax.swing.JLabel jLabel1;
  private javax.swing.JScrollPane jScrollPane1;
  private javax.swing.JToolBar jToolBar1;
  private javax.swing.JList list;
  private javax.swing.JLabel status;
  // End of variables declaration//GEN-END:variables

  private DefaultListModel model = new DefaultListModel();
  private boolean active;

  public static class Interface {
    public String dev;
    public boolean dhcp4 = true, dhcp6 = false;
    public boolean disableIP6 = true;
    public String ip4, mask4, gateway4;
    public String ip6, gateway6;
  }

  public static class Config {
    public Interface iface[];
    public String dns1, dns2, dns3;
    public String hostname, domain;
  }

  private Config config;
  private String configFolder = "/etc/jconfig.d/";
  private String configFile = "network.xml";

  private void loadConfig() {
    defaultConfig();
    try {
      XML xml = new XML();
      FileInputStream fis = new FileInputStream(configFolder + configFile);
      xml.read(fis);
      xml.writeClass(config);
    } catch (FileNotFoundException e1) {
      defaultConfig();
    } catch (Exception e2) {
      JFLog.log(e2);
      defaultConfig();
    }
  }

  private void defaultConfig() {
    config = new Config();
    config.iface = new Interface[0];
    config.hostname = "localhost";
    config.domain = "localdomain";
    config.dns1 = "";
    config.dns2 = "";
    config.dns3 = "";
  }

  private void saveConfig() {
    try {
      XML xml = new XML();
      File tmpFile = File.createTempFile("network", ".xml");
      FileOutputStream fos = new FileOutputStream(tmpFile);
      xml.readClass("network", config);
      xml.write(fos);
      fos.close();
      Linux.mkdir(configFolder);
      if (!Linux.copyFile(tmpFile.getAbsolutePath(), configFolder + configFile)) {
        tmpFile.delete();
        throw new Exception("file io error");
      }
      tmpFile.delete();
    } catch (Exception e) {
      JFLog.log(e);
    }
  }

  private Interface getInterface(String dev) {
    for(int a=0;a<config.iface.length;a++) {
      if (config.iface[a].dev.equals(dev)) return config.iface[a];
    }
    Interface iface = new Interface();
    iface.dev = dev;
    config.iface = Arrays.copyOf(config.iface, config.iface.length + 1);
    config.iface[config.iface.length-1] = iface;
    return iface;
  }

  private void listIFs() {
    model.clear();
    ShellProcess sp = new ShellProcess();
    String output = sp.run(new String[] {"ifconfig", "-a"}, false);
    String lns[] = output.split("\n");
    for(int a=0;a<lns.length;a++) {
      if (!lns[a].startsWith(" ")) {
        int idx = lns[a].indexOf(" ");
        if (idx == -1) continue;
        String ifName = lns[a].substring(0,idx);
        if (ifName.endsWith(":")) ifName = ifName.substring(0, ifName.length()-1);
        model.addElement(ifName);
      }
    }
  }

  private void isInterfaceActive() {
    String eth = (String)list.getSelectedValue();
    if (eth == null) {
      enable.setText("Enable");
      enable.setEnabled(false);
      edit.setEnabled(false);
      status.setText("Status : n/a");
      return;
    }
    ShellProcess sp = new ShellProcess();
    String output = sp.run(new String[] {"ifconfig"}, false);
    String lns[] = output.split("\n");
    active = false;
    for(int a=0;a<lns.length;a++) {
      if (lns[a].startsWith(eth)) {
        active = true;
      }
    }
    enable.setText( (active ? "Disable" : "Enable"));
    enable.setEnabled(true);
    edit.setEnabled(true);
    status.setText( (active ? "Active" : "Inactive"));
  }

  private void toggleIF() {
    String eth = (String)list.getSelectedValue();
    if (eth == null) return;
    if (false) {
      //exec : sudo ifconfig [eth?] up/down
      ShellProcess sp = new ShellProcess();
      String output = sp.run(new String[] {"sudo", "ifconfig", eth, (active ? "down" : "up")}, false);
    } else {
      //use jnetworkmgr instead
      ConfigApp.jbusClient.call("org.jflinux.jnetworkmgr", (active ? "ifDown" : "ifUp"), '\"' + eth + '\"');
      JF.sleep(250);
    }
    isInterfaceActive();
  }
}
